package com.hk.core.web.client;

import com.hk.commons.util.AssertUtils;
import com.hk.commons.util.SpringContextHolder;
import com.hk.core.web.Webs;
import org.springframework.core.io.InputStreamResource;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.web.client.RestTemplate;

import java.util.Map;
import java.util.Objects;

/**
 * @author Kevin
 * @date 2024-07-07 22:18
 */
public class RestTemplates {

    private static RestTemplate restTemplate;

    private static RestTemplate getRestTemplate() {
        if (Objects.isNull(RestTemplates.restTemplate)) {
            restTemplate = SpringContextHolder.getBean(RestTemplate.class);
        }
        return RestTemplates.restTemplate;
    }

    public static <T> T get(String url, Map<String, ?> params, Class<T> responseType) {
        return get(url, params, new HttpHeaders(), responseType);
    }

    public static <T> T get(String url, Map<String, ?> params, HttpHeaders headers, Class<T> responseType) {
        return getResponseEntity(url, params, headers, responseType).getBody();
    }

    public static <T> ResponseEntity<T> getResponseEntity(String url, Map<String, ?> params, HttpHeaders headers, Class<T> responseType) {
        RestTemplate template = getRestTemplate();
        AssertUtils.notNull(template, "RestTemplate is null");
        return template.exchange(Webs.buildUrl(url, params), HttpMethod.GET, new HttpEntity<>(headers), responseType);
    }

    public static ResponseEntity<InputStreamResource> getForStream(String url, Map<String, ?> params) {
        return getResponseEntity(url, params, null, InputStreamResource.class);
    }

    public static <T> T post(String url, Map<String, ?> params, Class<T> responseType) {
        return post(url, params, null, null, responseType);
    }

    public static <T> T post(String url, Object body, Class<T> responseType) {
        return post(url, null, body, null, responseType);
    }

    public static <T> T post(String url, Map<String, ?> params, Object body, HttpHeaders headers, Class<T> responseType) {
        return postResponseEntity(url, params, body, headers, responseType).getBody();
    }

    /**
     * post 请求
     *
     * @param url          url
     * @param params       请求参数
     * @param body         请求数据，对于文件上传的请求，需要用 HttpHeaders包装一层
     *                     <pre> {@code
     *                     MultiValueMap<String,Object> requestParams = new LinkedMultiValueMap<>();
     *                     requestParams.add("id","value"); 普通参数
     *
     *                     HttpHeaders h = new HttpHeaders();
     *                     h.setContentType(MediaType.IMAGE_PNG); // 设置请求附件的content-type
     *                     requestParams.add("file",new HttpEntity(new ByteArrayResource("value".getBytes()), h);
     *
     *                     HttpHeaders headers = new HttpHeaders();
     *                     headers.setContentType(MediaType.MULTIPART_FORM_DATA); // 设置请求的content-type
     *                     RestTemplates.postResponseEntity("url", null, requestParams, headers, String.class);
     *                     }}</pre>
     * @param headers      请求头
     * @param responseType 返回值类型
     */
    public static <T> ResponseEntity<T> postResponseEntity(String url, Map<String, ?> params, Object body, HttpHeaders headers, Class<T> responseType) {
        RestTemplate template = getRestTemplate();
        AssertUtils.notNull(template, "RestTemplate is null");
        return template.exchange(Webs.buildUrl(url, params), HttpMethod.POST, new HttpEntity<>(body, headers), responseType);
    }
}
